"""
任务编辑对话框模块
提供图形化的任务创建和编辑界面
"""

import pygame
import sys
from datetime import datetime, date, timedelta
from typing import Optional, Dict, Any, Tuple


class Colors:
    """颜色定义"""
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    GRAY = (128, 128, 128)
    LIGHT_GRAY = (240, 240, 240)
    DARK_GRAY = (64, 64, 64)
    BLUE = (0, 122, 255)
    LIGHT_BLUE = (173, 216, 230)
    RED = (255, 59, 48)
    GREEN = (52, 199, 89)
    ORANGE = (255, 149, 0)
    YELLOW = (255, 204, 0)


class InputField:
    """输入框组件"""
    
    def __init__(self, x: int, y: int, width: int, height: int, 
                 placeholder: str = "", max_length: int = 100):
        self.rect = pygame.Rect(x, y, width, height)
        self.placeholder = placeholder
        self.text = ""
        self.max_length = max_length
        self.active = False
        self.cursor_pos = 0
        self.cursor_visible = True
        self.cursor_timer = 0
        self.font = pygame.font.Font(None, 24)
        
    def handle_event(self, event):
        """处理输入事件"""
        if event.type == pygame.MOUSEBUTTONDOWN:
            self.active = self.rect.collidepoint(event.pos)
            
        elif event.type == pygame.KEYDOWN and self.active:
            if event.key == pygame.K_BACKSPACE:
                if self.cursor_pos > 0:
                    self.text = self.text[:self.cursor_pos-1] + self.text[self.cursor_pos:]
                    self.cursor_pos -= 1
            elif event.key == pygame.K_DELETE:
                if self.cursor_pos < len(self.text):
                    self.text = self.text[:self.cursor_pos] + self.text[self.cursor_pos+1:]
            elif event.key == pygame.K_LEFT:
                self.cursor_pos = max(0, self.cursor_pos - 1)
            elif event.key == pygame.K_RIGHT:
                self.cursor_pos = min(len(self.text), self.cursor_pos + 1)
            elif event.key == pygame.K_HOME:
                self.cursor_pos = 0
            elif event.key == pygame.K_END:
                self.cursor_pos = len(self.text)
            elif len(self.text) < self.max_length and event.unicode.isprintable():
                self.text = self.text[:self.cursor_pos] + event.unicode + self.text[self.cursor_pos:]
                self.cursor_pos += 1
    
    def update(self, dt):
        """更新光标闪烁"""
        if self.active:
            self.cursor_timer += dt
            if self.cursor_timer >= 500:  # 500ms闪烁间隔
                self.cursor_visible = not self.cursor_visible
                self.cursor_timer = 0
    
    def draw(self, screen):
        """绘制输入框"""
        # 绘制背景
        color = Colors.WHITE if self.active else Colors.LIGHT_GRAY
        border_color = Colors.BLUE if self.active else Colors.GRAY
        pygame.draw.rect(screen, color, self.rect)
        pygame.draw.rect(screen, border_color, self.rect, 2)
        
        # 绘制文本
        display_text = self.text if self.text else self.placeholder
        text_color = Colors.BLACK if self.text else Colors.GRAY
        
        text_surface = self.font.render(display_text, True, text_color)
        text_rect = text_surface.get_rect()
        text_rect.left = self.rect.left + 8
        text_rect.centery = self.rect.centery
        
        # 裁剪文本以适应输入框
        clip_rect = pygame.Rect(self.rect.left + 8, self.rect.top, 
                               self.rect.width - 16, self.rect.height)
        screen.set_clip(clip_rect)
        screen.blit(text_surface, text_rect)
        screen.set_clip(None)
        
        # 绘制光标
        if self.active and self.cursor_visible and self.text:
            cursor_text = self.text[:self.cursor_pos]
            cursor_width = self.font.size(cursor_text)[0]
            cursor_x = self.rect.left + 8 + cursor_width
            cursor_y1 = self.rect.top + 4
            cursor_y2 = self.rect.bottom - 4
            pygame.draw.line(screen, Colors.BLACK, (cursor_x, cursor_y1), (cursor_x, cursor_y2), 1)


class DropdownField:
    """下拉选择框组件"""
    
    def __init__(self, x: int, y: int, width: int, height: int, 
                 options: list, default_value: str = ""):
        self.rect = pygame.Rect(x, y, width, height)
        self.options = options
        self.selected_value = default_value if default_value in options else (options[0] if options else "")
        self.is_open = False
        self.font = pygame.font.Font(None, 24)
        self.option_height = 30
        
    def handle_event(self, event):
        """处理下拉框事件"""
        if event.type == pygame.MOUSEBUTTONDOWN:
            if self.rect.collidepoint(event.pos):
                self.is_open = not self.is_open
            elif self.is_open:
                # 检查是否点击了选项
                for i, option in enumerate(self.options):
                    option_rect = pygame.Rect(
                        self.rect.x, 
                        self.rect.bottom + i * self.option_height,
                        self.rect.width, 
                        self.option_height
                    )
                    if option_rect.collidepoint(event.pos):
                        self.selected_value = option
                        self.is_open = False
                        return
                self.is_open = False
    
    def draw(self, screen):
        """绘制下拉框"""
        # 绘制主框
        pygame.draw.rect(screen, Colors.WHITE, self.rect)
        pygame.draw.rect(screen, Colors.GRAY, self.rect, 2)
        
        # 绘制选中的值
        text_surface = self.font.render(self.selected_value, True, Colors.BLACK)
        text_rect = text_surface.get_rect()
        text_rect.left = self.rect.left + 8
        text_rect.centery = self.rect.centery
        screen.blit(text_surface, text_rect)
        
        # 绘制下拉箭头
        arrow_x = self.rect.right - 20
        arrow_y = self.rect.centery
        if self.is_open:
            # 向上箭头
            pygame.draw.polygon(screen, Colors.GRAY, [
                (arrow_x, arrow_y + 3),
                (arrow_x + 6, arrow_y - 3),
                (arrow_x + 12, arrow_y + 3)
            ])
        else:
            # 向下箭头
            pygame.draw.polygon(screen, Colors.GRAY, [
                (arrow_x, arrow_y - 3),
                (arrow_x + 6, arrow_y + 3),
                (arrow_x + 12, arrow_y - 3)
            ])
        
        # 绘制下拉选项
        if self.is_open:
            for i, option in enumerate(self.options):
                option_rect = pygame.Rect(
                    self.rect.x, 
                    self.rect.bottom + i * self.option_height,
                    self.rect.width, 
                    self.option_height
                )
                
                # 背景
                pygame.draw.rect(screen, Colors.WHITE, option_rect)
                pygame.draw.rect(screen, Colors.GRAY, option_rect, 1)
                
                # 文本
                option_surface = self.font.render(option, True, Colors.BLACK)
                option_text_rect = option_surface.get_rect()
                option_text_rect.left = option_rect.left + 8
                option_text_rect.centery = option_rect.centery
                screen.blit(option_surface, option_text_rect)


class DatePicker:
    """日期选择器组件"""
    
    def __init__(self, x: int, y: int, width: int, height: int, 
                 default_date: Optional[date] = None):
        self.rect = pygame.Rect(x, y, width, height)
        self.selected_date = default_date or date.today()
        self.font = pygame.font.Font(None, 24)
        self.is_open = False
        self.calendar_rect = pygame.Rect(x, y + height, 280, 200)
        
    def handle_event(self, event):
        """处理日期选择事件"""
        if event.type == pygame.MOUSEBUTTONDOWN:
            if self.rect.collidepoint(event.pos):
                self.is_open = not self.is_open
            elif self.is_open and not self.calendar_rect.collidepoint(event.pos):
                self.is_open = False
    
    def draw(self, screen):
        """绘制日期选择器"""
        # 绘制主框
        pygame.draw.rect(screen, Colors.WHITE, self.rect)
        pygame.draw.rect(screen, Colors.GRAY, self.rect, 2)
        
        # 绘制日期文本
        date_text = self.selected_date.strftime('%Y-%m-%d')
        text_surface = self.font.render(date_text, True, Colors.BLACK)
        text_rect = text_surface.get_rect()
        text_rect.left = self.rect.left + 8
        text_rect.centery = self.rect.centery
        screen.blit(text_surface, text_rect)
        
        # 绘制日历图标
        icon_x = self.rect.right - 25
        icon_y = self.rect.centery - 8
        pygame.draw.rect(screen, Colors.GRAY, (icon_x, icon_y, 16, 16), 2)
        pygame.draw.line(screen, Colors.GRAY, (icon_x + 4, icon_y - 2), (icon_x + 4, icon_y + 2))
        pygame.draw.line(screen, Colors.GRAY, (icon_x + 12, icon_y - 2), (icon_x + 12, icon_y + 2))
        
        # 绘制简化的日历（如果打开）
        if self.is_open:
            pygame.draw.rect(screen, Colors.WHITE, self.calendar_rect)
            pygame.draw.rect(screen, Colors.GRAY, self.calendar_rect, 2)
            
            # 显示快捷日期选项
            quick_dates = [
                ("今天", date.today()),
                ("明天", date.today() + timedelta(days=1)),
                ("一周后", date.today() + timedelta(days=7)),
                ("一个月后", date.today() + timedelta(days=30))
            ]
            
            for i, (label, quick_date) in enumerate(quick_dates):
                option_rect = pygame.Rect(
                    self.calendar_rect.x + 10,
                    self.calendar_rect.y + 10 + i * 35,
                    260, 30
                )
                
                # 检查鼠标悬停
                mouse_pos = pygame.mouse.get_pos()
                if option_rect.collidepoint(mouse_pos):
                    pygame.draw.rect(screen, Colors.LIGHT_BLUE, option_rect)
                    # 检查点击
                    if pygame.mouse.get_pressed()[0]:
                        self.selected_date = quick_date
                        self.is_open = False
                
                # 绘制选项文本
                option_text = f"{label} ({quick_date.strftime('%Y-%m-%d')})"
                text_surface = self.font.render(option_text, True, Colors.BLACK)
                text_rect = text_surface.get_rect()
                text_rect.left = option_rect.left + 5
                text_rect.centery = option_rect.centery
                screen.blit(text_surface, text_rect)


class TaskDialog:
    """任务编辑对话框"""
    
    def __init__(self, screen_width: int, screen_height: int, task_data: Optional[Dict] = None):
        self.screen_width = screen_width
        self.screen_height = screen_height
        
        # 对话框尺寸和位置
        self.dialog_width = 500
        self.dialog_height = 450
        self.dialog_x = (screen_width - self.dialog_width) // 2
        self.dialog_y = (screen_height - self.dialog_height) // 2
        self.dialog_rect = pygame.Rect(self.dialog_x, self.dialog_y, self.dialog_width, self.dialog_height)
        
        # 字体
        self.title_font = pygame.font.Font(None, 32)
        self.label_font = pygame.font.Font(None, 24)
        
        # 初始化表单字段
        self._init_form_fields(task_data)
        
        # 对话框状态
        self.is_open = False
        self.result = None
        
    def _init_form_fields(self, task_data: Optional[Dict]):
        """初始化表单字段"""
        base_x = self.dialog_x + 20
        base_y = self.dialog_y + 60
        field_width = self.dialog_width - 40
        field_height = 35
        
        # 任务标题
        self.title_field = InputField(
            base_x, base_y, field_width, field_height,
            placeholder="请输入任务标题...", max_length=100
        )
        
        # 任务描述
        self.description_field = InputField(
            base_x, base_y + 70, field_width, field_height * 2,
            placeholder="请输入任务描述...", max_length=500
        )
        
        # 优先级选择
        self.priority_field = DropdownField(
            base_x, base_y + 170, field_width // 2 - 10, field_height,
            options=["high", "medium", "low"], default_value="medium"
        )
        
        # 分类输入
        self.category_field = InputField(
            base_x + field_width // 2 + 10, base_y + 170, field_width // 2 - 10, field_height,
            placeholder="分类", max_length=50
        )
        
        # 截止日期选择
        self.due_date_field = DatePicker(
            base_x, base_y + 240, field_width, field_height,
            default_date=date.today() + timedelta(days=7)
        )
        
        # 如果有任务数据，填充表单
        if task_data:
            self.title_field.text = task_data.get('title', '')
            self.description_field.text = task_data.get('description', '')
            self.priority_field.selected_value = task_data.get('priority', 'medium')
            self.category_field.text = task_data.get('category', '')
            
            # 解析日期
            if task_data.get('due_date'):
                try:
                    self.due_date_field.selected_date = datetime.strptime(
                        task_data['due_date'], '%Y-%m-%d'
                    ).date()
                except:
                    pass
    
    def open(self):
        """打开对话框"""
        self.is_open = True
        self.result = None
    
    def close(self):
        """关闭对话框"""
        self.is_open = False
    
    def handle_event(self, event):
        """处理对话框事件"""
        if not self.is_open:
            return
        
        # 处理表单字段事件
        self.title_field.handle_event(event)
        self.description_field.handle_event(event)
        self.priority_field.handle_event(event)
        self.category_field.handle_event(event)
        self.due_date_field.handle_event(event)
        
        # 处理按钮点击
        if event.type == pygame.MOUSEBUTTONDOWN:
            mouse_x, mouse_y = event.pos
            
            # 确定按钮
            confirm_btn_rect = pygame.Rect(
                self.dialog_x + self.dialog_width - 180,
                self.dialog_y + self.dialog_height - 50,
                80, 35
            )
            
            # 取消按钮
            cancel_btn_rect = pygame.Rect(
                self.dialog_x + self.dialog_width - 90,
                self.dialog_y + self.dialog_height - 50,
                80, 35
            )
            
            if confirm_btn_rect.collidepoint(mouse_x, mouse_y):
                # 验证并返回结果
                if self.title_field.text.strip():
                    self.result = {
                        'action': 'confirm',
                        'data': {
                            'title': self.title_field.text.strip(),
                            'description': self.description_field.text.strip(),
                            'priority': self.priority_field.selected_value,
                            'category': self.category_field.text.strip() or None,
                            'due_date': self.due_date_field.selected_date.strftime('%Y-%m-%d')
                        }
                    }
                    self.close()
            
            elif cancel_btn_rect.collidepoint(mouse_x, mouse_y):
                self.result = {'action': 'cancel'}
                self.close()
            
            # 点击对话框外部关闭
            elif not self.dialog_rect.collidepoint(mouse_x, mouse_y):
                self.result = {'action': 'cancel'}
                self.close()
    
    def update(self, dt):
        """更新对话框"""
        if self.is_open:
            self.title_field.update(dt)
            self.description_field.update(dt)
    
    def draw(self, screen):
        """绘制对话框"""
        if not self.is_open:
            return
        
        # 绘制半透明背景
        overlay = pygame.Surface((self.screen_width, self.screen_height))
        overlay.set_alpha(128)
        overlay.fill(Colors.BLACK)
        screen.blit(overlay, (0, 0))
        
        # 绘制对话框背景
        pygame.draw.rect(screen, Colors.WHITE, self.dialog_rect)
        pygame.draw.rect(screen, Colors.GRAY, self.dialog_rect, 2)
        
        # 绘制标题
        title_text = "添加任务" if not hasattr(self, 'edit_mode') else "编辑任务"
        title_surface = self.title_font.render(title_text, True, Colors.BLACK)
        title_rect = title_surface.get_rect()
        title_rect.centerx = self.dialog_rect.centerx
        title_rect.y = self.dialog_y + 15
        screen.blit(title_surface, title_rect)
        
        # 绘制标签
        labels = [
            ("任务标题:", self.dialog_y + 40),
            ("任务描述:", self.dialog_y + 110),
            ("优先级:", self.dialog_y + 150),
            ("分类:", self.dialog_y + 150),
            ("截止日期:", self.dialog_y + 220)
        ]
        
        for i, (label, y) in enumerate(labels):
            label_surface = self.label_font.render(label, True, Colors.DARK_GRAY)
            if i == 3:  # 分类标签位置调整
                x = self.dialog_x + self.dialog_width // 2 + 10
            else:
                x = self.dialog_x + 20
            screen.blit(label_surface, (x, y))
        
        # 绘制表单字段
        self.title_field.draw(screen)
        self.description_field.draw(screen)
        self.priority_field.draw(screen)
        self.category_field.draw(screen)
        self.due_date_field.draw(screen)
        
        # 绘制按钮
        # 确定按钮
        confirm_btn_rect = pygame.Rect(
            self.dialog_x + self.dialog_width - 180,
            self.dialog_y + self.dialog_height - 50,
            80, 35
        )
        pygame.draw.rect(screen, Colors.BLUE, confirm_btn_rect)
        confirm_text = self.label_font.render("确定", True, Colors.WHITE)
        confirm_text_rect = confirm_text.get_rect(center=confirm_btn_rect.center)
        screen.blit(confirm_text, confirm_text_rect)
        
        # 取消按钮
        cancel_btn_rect = pygame.Rect(
            self.dialog_x + self.dialog_width - 90,
            self.dialog_y + self.dialog_height - 50,
            80, 35
        )
        pygame.draw.rect(screen, Colors.GRAY, cancel_btn_rect)
        cancel_text = self.label_font.render("取消", True, Colors.WHITE)
        cancel_text_rect = cancel_text.get_rect(center=cancel_btn_rect.center)
        screen.blit(cancel_text, cancel_text_rect)
    
    def get_result(self) -> Optional[Dict]:
        """获取对话框结果"""
        result = self.result
        self.result = None
        return result